do

Network = {}


-- 回调
-- 客户端每发一个请求都会注册一个回调，回调的唯一的，并且仅触发一次。一般做法是生成一个唯一key来进行回调映射并且作为发送的packet.id值，服务器会在返回的packet中透传回客户端
local callbacks = {}

-- 监听器
-- 监听器的主要作用是，监听服务器主动推送的消息监听。便于我们处理代码业务
local listeners = {}


-- 解码器：
-- 之所有此处还需要一次解码，是因为在网络传输过程中所有的消息key是转为了hashcode进行传输，
-- 占用字节更少，所以需要把hashcode转回我们代码中使用的字符key。节约宽带提高传输效率
-- 如果是不传数字key时，可以删除解码器
decoders = {}

-- 结构体
structs = {}

-- 注册回调(回调函数,上下文)
local registerCallback = function (callback, context)
   if callback then
       callbacks[callbackKey] = {callback, context}
    end
end

-- 注册监听器(监听处理函数)
local registerListener = function (callback)
   if callback then
       callbacks[callbackKey] = {callback}
    end
end


-- 分发器、接收服务器消息的唯一入口，便于处理错误码等情况
Network.disp = function(packet)
	-- 回调
	local callback = callbacks[callbacks.Id];
	-- 监听
	local listener = listeners[callbacks.CommandId];

	if packet.status ~= 0 then
		-- 错误码提示:

	else
		-- 消息解码
		local result = Network.decoder[callbacks.CommandId](packet.Body)

		-- 执行回调
		if callback then
			pcall(callback[1], callback[2], result)
		end

		-- 执行监听
		if listener then
			pcall(listener[1], result)
		end
	end

	-- 移除回调
	if callback then
		callbacks[callbacks.Id] = nil
	end

end

-- 发送消息模块，类似RPC调用，调用者不必关心内部实现
Network.module = {
    Chat = {
        -- 发送聊天
        sendMessage = function(chatType,content,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 324550495

            packet.Body = {}
            packet.Body[1437412018] = objectEncode(chatType);
            packet.Body[951530617] = objectEncode(content);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
    },
    Friend = {
        -- 操作好友
        operationFriend = function(action,friendIds,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 178152165

            packet.Body = {}
            packet.Body[-1422950858] = objectEncode(action);
            packet.Body[-1165056198] = objectEncode(friendIds);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
        -- 备注好友
        remarkFriend = function(friendId,remark,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 178133566

            packet.Body = {}
            packet.Body[-1423055783] = objectEncode(friendId);
            packet.Body[-934624384] = objectEncode(remark);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
    },
    Mail = {
        -- 读取邮件
        read = function(id,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 95902102

            packet.Body = {}
            packet.Body[3355] = objectEncode(id);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
        -- 删除邮件
        delete = function(id,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 95880619

            packet.Body = {}
            packet.Body[3355] = objectEncode(id);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
        -- 收取邮件
        receive = function(id,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 95908579

            packet.Body = {}
            packet.Body[3355] = objectEncode(id);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
    },
    Player = {
        -- 进入游戏
        enterGame = function(loginServerId,token,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 450960106

            packet.Body = {}
            packet.Body[451300935] = objectEncode(loginServerId);
            packet.Body[110541305] = objectEncode(token);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
    },
    Prop = {
        -- 使用物品
        useProp = function(num,propId,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 593707402

            packet.Body = {}
            packet.Body[109446] = objectEncode(num);
            packet.Body[-979804194] = objectEncode(propId);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
    },
    Store = {
        -- 购买商品
        buyGoods = function(id,num,storeId,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 2028031088

            packet.Body = {}
            packet.Body[3355] = objectEncode(id);
            packet.Body[109446] = objectEncode(num);
            packet.Body[-1884271140] = objectEncode(storeId);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
    },
    Task = {
        -- 提交任务
        submit = function(id,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 897925144

            packet.Body = {}
            packet.Body[3355] = objectEncode(id);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
        -- 发送任务
        sendTask = function(task,callback,context)

            -- 1.包封装
            local packet = {}
            packet.Id = os.time()
            packet.CommandId = 897938733

            packet.Body = {}
            packet.Body[3552645] = objectEncode(task);

            -- 2.注册回调
            registerCallback(callback,context)

            -- 3.执行发送
            socket.send(packet);
        end,
    },
}

-- *************** 解码器 ***************

-- 发送聊天
decoders[324550495] = function(body)
    local o = {}
    return o;
end

-- 推送聊天
decoders[324562046] = function(body)
    local o = {}
    o.msg = objectDecode(body[108417]);
    return o;
end


-- 操作好友
decoders[178152165] = function(body)
    local o = {}
    return o;
end
-- 备注好友
decoders[178133566] = function(body)
    local o = {}
    return o;
end

-- 推送好友
decoders[178139975] = function(body)
    local o = {}
    o.ids = objectDecode(body[104120]);
    o.list = objectDecode(body[3322014]);
    return o;
end


-- 读取邮件
decoders[95902102] = function(body)
    local o = {}
    return o;
end
-- 删除邮件
decoders[95880619] = function(body)
    local o = {}
    return o;
end
-- 收取邮件
decoders[95908579] = function(body)
    local o = {}
    return o;
end

-- 推送邮件
decoders[95893705] = function(body)
    local o = {}
    o.mails = objectDecode(body[103657884]);
    return o;
end


-- 进入游戏
decoders[450960106] = function(body)
    local o = {}
    o.player = objectDecode(body[-985752863]);
    return o;
end

-- 推送
decoders[450970506] = function(body)
    local o = {}
    o.loginServerId = objectDecode(body[451300935]);
    o.token = objectDecode(body[110541305]);
    return o;
end


-- 使用物品
decoders[593707402] = function(body)
    local o = {}
    o.reward = objectDecode(body[-934326481]);
    return o;
end

-- 推送物品
decoders[593715788] = function(body)
    local o = {}
    o.props = objectDecode(body[106940784]);
    return o;
end


-- 购买商品
decoders[2028031088] = function(body)
    local o = {}
    return o;
end

-- 刷新商品
decoders[2028021051] = function(body)
    local o = {}
    o.goodsId = objectDecode(body[207037201]);
    o.storeId = objectDecode(body[-1884271140]);
    return o;
end


-- 提交任务
decoders[897925144] = function(body)
    local o = {}
    return o;
end
-- 发送任务
decoders[897938733] = function(body)
    local o = {}
    return o;
end

-- 更新任务
decoders[897923273] = function(body)
    local o = {}
    o.tasks = objectDecode(body[110132110]);
    return o;
end





-- *************** 结构体 ***************

-- 用户信息
UserDTO = {
    encode = function(o)
        local r = {};
        r[115792] = o.uid    -- 
        return r
    end,
    decode = function(o)
        local r = {};
        r.uid = objectDecode(o[115792]);    -- 
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = 1517493748
        return r
    end
}

-- 玩家简单信息
PlayerInfoDTO = {
    encode = function(o)
        local r = {};
        r[115792] = o.uid    -- 用户ID
        r[110987] = o.pid    -- 玩家ID
        r[3373707] = o.name    -- 昵称
        r[107554] = o.lvl    -- 等级
        r[100893] = o.exp    -- 经验
        r[3226745] = o.icon    -- 头像
        r[3575610] = o.type    -- 类型
        return r
    end,
    decode = function(o)
        local r = {};
        r.uid = objectDecode(o[115792]);    -- 用户ID
        r.pid = objectDecode(o[110987]);    -- 玩家ID
        r.name = objectDecode(o[3373707]);    -- 昵称
        r.lvl = objectDecode(o[107554]);    -- 等级
        r.exp = objectDecode(o[100893]);    -- 经验
        r.icon = objectDecode(o[3226745]);    -- 头像
        r.type = objectDecode(o[3575610]);    -- 类型
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = 1102355472
        return r
    end
}

-- 目标玩家信息
TargetPlayerDTO = {
    encode = function(o)
        local r = {};
        return r
    end,
    decode = function(o)
        local r = {};
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = -684126067
        return r
    end
}

-- 玩家信息
PlayerDTO = {
    encode = function(o)
        local r = {};
        r[2095520559] = o.playerInfo    -- 基本信息
        r[99168185] = o.heros    -- 英雄
        r[103657884] = o.mails    -- 邮件
        r[106940784] = o.props    -- 道具
        r[110132110] = o.tasks    -- 任务
        r[42834518] = o.submitTasks    -- 已提交的任务
        return r
    end,
    decode = function(o)
        local r = {};
        r.playerInfo = objectDecode(o[2095520559]);    -- 基本信息
        r.heros = objectDecode(o[99168185]);    -- 英雄
        r.mails = objectDecode(o[103657884]);    -- 邮件
        r.props = objectDecode(o[106940784]);    -- 道具
        r.tasks = objectDecode(o[110132110]);    -- 任务
        r.submitTasks = objectDecode(o[42834518]);    -- 已提交的任务
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = 131897118
        return r
    end
}

-- 英雄
HeroDTO = {
    encode = function(o)
        local r = {};
        r[3355] = o.id    -- 唯一标示
        r[98494] = o.cid    -- 配置ID
        r[3466] = o.lv    -- 等级
        r[100893] = o.exp    -- 经验
        r[3004913] = o.attr    -- 属性
        return r
    end,
    decode = function(o)
        local r = {};
        r.id = objectDecode(o[3355]);    -- 唯一标示
        r.cid = objectDecode(o[98494]);    -- 配置ID
        r.lv = objectDecode(o[3466]);    -- 等级
        r.exp = objectDecode(o[100893]);    -- 经验
        r.attr = objectDecode(o[3004913]);    -- 属性
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = -1819011227
        return r
    end
}

-- 邮件
MailDTO = {
    encode = function(o)
        local r = {};
        r[3355] = o.id    -- 唯一标示
        r[110371416] = o.title    -- 标题
        r[951530617] = o.content    -- 内容
        r[100526016] = o.items    -- 附件
        r[-892481550] = o.status    -- 状态
        r[1369213417] = o.createTime    -- 创建时间(秒)
        return r
    end,
    decode = function(o)
        local r = {};
        r.id = objectDecode(o[3355]);    -- 唯一标示
        r.title = objectDecode(o[110371416]);    -- 标题
        r.content = objectDecode(o[951530617]);    -- 内容
        r.items = objectDecode(o[100526016]);    -- 附件
        r.status = objectDecode(o[-892481550]);    -- 状态
        r.createTime = objectDecode(o[1369213417]);    -- 创建时间(秒)
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = -1799377784
        return r
    end
}

-- 道具
PropDTO = {
    encode = function(o)
        local r = {};
        r[3355] = o.id    -- 唯一标示
        r[98494] = o.cid    -- 配置ID
        r[109446] = o.num    -- 数量
        return r
    end,
    decode = function(o)
        local r = {};
        r.id = objectDecode(o[3355]);    -- 唯一标示
        r.cid = objectDecode(o[98494]);    -- 配置ID
        r.num = objectDecode(o[109446]);    -- 数量
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = 1355489116
        return r
    end
}

-- 道具 -> 装备
EquipmentDTO = {
    encode = function(o)
        local r = PropDTO.encode(o);
        r[3466] = o.lv    -- 等级
        return r
    end,
    decode = function(o)
        local r = PropDTO.decode(o);
        r.lv = objectDecode(o[3466]);    -- 等级
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = -325130863
        return r
    end
}

-- 任务
TaskDTO = {
    encode = function(o)
        local r = {};
        r[3355] = o.id    -- 唯一标示
        r[98494] = o.cid    -- 配置ID
        r[-697920873] = o.schedule    -- 进度
        r[-892481550] = o.status    -- 状态
        return r
    end,
    decode = function(o)
        local r = {};
        r.id = objectDecode(o[3355]);    -- 唯一标示
        r.cid = objectDecode(o[98494]);    -- 配置ID
        r.schedule = objectDecode(o[-697920873]);    -- 进度
        r.status = objectDecode(o[-892481550]);    -- 状态
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = 127386106
        return r
    end
}

-- 聊天信息
ChatMsgDTO = {
    encode = function(o)
        local r = {};
        r[1437412018] = o.chatType    -- 聊天类型
        r[-905962955] = o.sender    -- 发送者
        r[951530617] = o.content    -- 内容
        return r
    end,
    decode = function(o)
        local r = {};
        r.chatType = objectDecode(o[1437412018]);    -- 聊天类型
        r.sender = objectDecode(o[-905962955]);    -- 发送者
        r.content = objectDecode(o[951530617]);    -- 内容
        return r
    end,
    new = function()
        local r = {}
        r[183928832] = 160702518
        return r
    end
}


-- 判断是否是数组
isArray = function(t)
    if t == nil then
        return false, 0;
    end
    local i = 0
    local ret = true;
    for _ in pairs(t) do
        i = i + 1
        if t[i] == nil then
            ret = false
        end
    end
    return ret, i
end

objectDecode = function(o)
    local isTable = type(o)
    if isTable == "table" then
        local isArray, len = isArray(o)
        if isArray then
            return listDecode(o)
        else
            local struct = structs[o[183928832]]
            if struct then
                return struct.decode(o)
            else
                return mapDecode(o)
            end
        end
    else
        return o;
    end
end

-- 解析List
listDecode = function(o)
    local ret = {};
    for i, v in pairs(o) do
        table.insert(ret, objectDecode(v))
    end
    return ret
end

mapDecode = function(map)
    local ret = {};
    for key, value in pairs(map) do
        ret[objectDecode(key)] = objectDecode(value)
    end
    return ret;
end



objectEncode = function(o)
    local isTable = type(o)
    if isTable == "table" then
        local isArray, len = isArray(o)
        if isArray then
            return listEncode(o)
        else
            local struct = structs[o[183928832]]
            if struct then
                local r = struct.encode(o)
                r[183928832] = o[183928832];
                return r;
            else
                return mapEncode(o)
            end
        end
    else
        return o;
    end
end

-- 解析List
listEncode = function(o)
    local ret = {};
    for i, v in pairs(o) do
        table.insert(ret, objectEncode(v))
    end
    return ret
end

mapEncode = function(map)
    local ret = {};
    for key, value in pairs(map) do
        ret[objectEncode(key)] = objectEncode(value)
    end
    return ret;
end



structs[1517493748] = UserDTO
structs[1102355472] = PlayerInfoDTO
structs[-684126067] = TargetPlayerDTO
structs[131897118] = PlayerDTO
structs[-1819011227] = HeroDTO
structs[-1799377784] = MailDTO
structs[1355489116] = PropDTO
structs[-325130863] = EquipmentDTO
structs[127386106] = TaskDTO
structs[160702518] = ChatMsgDTO

end
